﻿#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <assert.h>

//模拟实现memmove
//void* my_memmove(void* dest, void* src, size_t num)
//{
//	assert(dest && src);
//	void* ret = dest;
//	if (dest < src)
//	{
//		while (num--)
//		{
//			*(char*)dest = *(char*)src;
//			dest = (char*)dest + 1;
//			src = (char*)src + 1;
//		}
//	}
//	else
//	{
//		while (num--)
//		{
//			*((char*)dest + num)= *((char*)src + num);
//		}
//	}
//}
//int main()
//{
//	int arr[10] = { 0,1,2,3,4,5,6,7,8,9 };
//	my_memmove(arr, arr + 2, 20);
//	return 0;
//}

//给你两个按 非递减顺序 排列的整数数组 nums1 和 nums2，另有两个整数 m 和 n ，分别表示 nums1 和 nums2 中的元素数目。
//请你 合并 nums2 到 nums1 中，使合并后的数组同样按 非递减顺序 排列。
//注意：最终，合并后数组不应由函数返回，而是存储在数组 nums1 中。为了应对这种情况，nums1 的初始长度为 m + n，其中前 m 个元素表示应合并的元素，后 n 个元素为 0 ，应忽略。nums2 的长度为 n 。
//示例 1：
//输入：nums1 = [1, 2, 3, 0, 0, 0], m = 3, nums2 = [2, 5, 6], n = 3
//输出：[1, 2, 2, 3, 5, 6]
//解释：需要合并[1, 2, 3] 和[2, 5, 6] 。
//合并结果是[1, 2, 2, 3, 5, 6] ，其中斜体加粗标注的为 nums1 中的元素。
//示例 2：
//输入：nums1 = [1], m = 1, nums2 = [], n = 0
//输出：[1]
//解释：需要合并[1] 和[] 。
//合并结果是[1] 。
//
//
//void merge(int* nums1, int nums1Size, int m, int* nums2, int nums2Size, int n) {
//    int end1 = m - 1;
//    int end2 = n - 1;
//    int dest = m + n - 1;
//    while (end1 >= 0 && end2 >= 0)
//    {
//        if (nums1[end1] > nums2[end2])
//        {
//            nums1[dest--] = nums1[end1--];
//        }
//        else
//        {
//            nums1[dest--] = nums2[end2--];
//        }
//    }
//    while (end2 >= 0)
//    {
//        nums1[dest--] = nums2[end2--];
//    }
//}



//给你一个 升序排列 的数组 nums ，请你 原地 删除重复出现的元素，使每个元素 只出现一次 ，返回删除后数组的新长度。元素的 相对顺序 应该保持 一致 。
//由于在某些语言中不能改变数组的长度，所以必须将结果放在数组nums的第一部分。更规范地说，如果在删除重复项之后有 k 个元素，那么 nums 的前 k 个元素应该保存最终结果。
//将最终结果插入 nums 的前 k 个位置后返回 k 。
//不要使用额外的空间，你必须在 原地 修改输入数组 并在使用 O(1) 额外空间的条件下完成。
//判题标准 :
//系统会用下面的代码来测试你的题解:
//int[] nums = [...]; // 输入数组
//int[] expectedNums = [...]; // 长度正确的期望答案
//int k = removeDuplicates(nums); // 调用
//assert k == expectedNums.length;
//for (int i = 0; i < k; i++) {
//    assert nums[i] == expectedNums[i];
//}
//如果所有断言都通过，那么您的题解将被 通过。
//示例 1：
//输入：nums = [1, 1, 2]
//输出：2, nums = [1, 2, _]
//解释：函数应该返回新的长度 2 ，并且原数组 nums 的前两个元素被修改为 1, 2 。不需要考虑数组中超出新长度后面的元素。

//int removeDuplicates(int* nums, int numsSize) {
//    int dest = 0;
//    int src = 0;
//    while (src < numsSize)
//    {
//        if (nums[dest] != nums[src])
//        {
//            dest++;
//            nums[dest] = nums[src];
//        }
//        src++;
//    }
//    return dest + 1;
//}

#include <string.h>
//模拟实现memcpy
//void* my_memcpy(void* dest, void* src, size_t num)
//{
//	assert(dest && src);
//	void* ret = dest;
//	while (num--)
//	{
//		*(char*)dest = *(char*)src;
//		dest = (char*)dest + 1;
//		src = (char*)src + 1;
//	}
//	return ret;
//}
//
//int main()
//{
//	int arr1[10] = { 0,1,2,3,4,5,6,7,8,9 };
//	int arr2[10] = { 0 };
//	my_memcpy(arr2+1, arr1 + 1, 20);
//	return 0;
//}

void* my_memmove(void* dest, void* src, size_t num)
{
	assert(dest && src);
	void* ret = dest;

	if (dest < src)
	{
		while (num--)
		{
			*(char*)dest = *(char*)src;
			dest = (char*)dest + 1;
			src = (char*)src + 1;
		}
	}
	else
	{
		while (num--)
		{
			*((char*)dest + num) = *((char*)src + num);
		}
	}
	return ret;
}

int main()
{
	int arr1[10] = { 0,1,2,3,4,5,6,7,8,9 };
	int arr2[10] = { 0 };
	my_memmove(arr1+2, arr1 + 1, 20);
	return 0;
}
